home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 18
/
AMIGAplus Sonderheft 18 (1999)(ICP)(DE)[!].iso
/
PD
/
Anwendungen
/
FS1541-13
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-01-03
|
11KB
|
325 lines
/*
* FS1541 - the handler entry point
*
* Copyright (C) 1996 - 1998 Michael Krause
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <string.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/dostags.h>
#include <dos/filehandler.h>
#include <utility/utility.h>
#include <devices/timer.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include "main.h"
#include "packet.h"
#include "disk.h"
#include "volume.h"
#include "support.h"
char verstring[] = "$VER: 1541-handler 1.3 (1.1.99)";
struct ExecBase *SysBase;
struct DosLibrary *DOSBase;
struct UtilityBase *UtilityBase, *__UtilityBase;
struct Task *ourtask;
struct MsgPort *ourport;
struct FileSysStartupMsg *fssm;
static UBYTE diskinfo_image[] = {
0xE3,0x10,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x3D,0x00,0x37,0x00,0x2A,
0x00,0x04,0x00,0x01,0x00,0x01,0x07,0x57,0x3F,0xD0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x01,0x10,0x07,0x57,0x66,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,
0x00,0x3D,0x07,0x5B,0xCB,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,
0x00,0x30,0x01,0x64,0x00,0xB7,0xFF,0xFF,0x00,0x00,0x00,0x00,0x02,0x00,0x12,0x7F,
0x07,0x5B,0xCB,0x66,0x00,0x00,0x00,0x00,0x07,0x57,0x66,0xBC,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x5A,0x00,0x45,0xFF,0xFF,0xFF,0xFF,0x00,0x01,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x00,0x29,0x00,0x02,
0x00,0x03,0x3A,0xD0,0x03,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xC0,0x00,0x00,0x00,
0x1E,0x00,0xFF,0xFF,0xC0,0x00,0x00,0x00,0x1E,0x00,0xFF,0xFF,0xC0,0xF8,0x0B,0xAA,
0x1E,0x00,0xFF,0xFF,0xC1,0xFB,0xCA,0x2A,0x1E,0x00,0xFF,0xFF,0xC1,0x83,0x8A,0x2A,
0x1E,0x00,0xFF,0xFF,0xC1,0x80,0x0B,0x1A,0x1E,0x00,0xFF,0xFF,0xC1,0x83,0x88,0x8A,
0x1E,0x00,0x3F,0xFF,0xC1,0xFB,0xCA,0x8A,0x18,0x00,0x3F,0xFF,0xC0,0xF8,0x0B,0x8A,
0x18,0x00,0x3F,0xFF,0xC0,0x00,0x00,0x00,0x18,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFC,0x00,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,
0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,0xFE,0x00,0xFF,0xFF,0xF8,0x00,0x7F,0xFF,
0xFE,0x00,0xFF,0xFF,0xFC,0x00,0x7F,0xFF,0xFE,0x00,0xFF,0xFF,0xFE,0x01,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0x87,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xEF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x00,0x3F,0xFF,0xFF,0xFF,0xE0,0x00,0x80,0x00,0x3F,0xFF,0xFF,0xFF,
0xE0,0x00,0x80,0x00,0x3F,0x07,0xF4,0x55,0xE0,0x00,0x80,0x00,0x3E,0x04,0x35,0xD5,
0xE0,0x00,0x80,0x00,0x3E,0x7C,0x75,0xD5,0xE0,0x00,0x80,0x00,0x3E,0x7F,0xF4,0xE5,
0xE0,0x00,0x80,0x00,0x3E,0x7C,0x77,0x75,0xE0,0x00,0x20,0x00,0x3E,0x04,0x35,0x75,
0xE0,0x00,0x20,0x00,0x3F,0x07,0xF4,0x75,0xE0,0x00,0x20,0x00,0x3F,0xFF,0xFF,0xFF,
0xE0,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x04,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x04,0x20,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x20,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x54,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x28,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x10,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x53,0x59,
0x53,0x3A,0x53,0x79,0x73,0x74,0x65,0x6D,0x2F,0x44,0x69,0x73,0x6B,0x43,0x6F,0x70,
0x79,0x00,0x00,0x00,0x00,0x02,0x00,0x02
};
UBYTE *diskiconimg = diskinfo_image;
int diskiconlength = sizeof(diskinfo_image);
static ULONG argarray[6] = { 0, 0, 0, 0, 0, 0 };
/*-------------------------------------------------------------------------*/
static BOOL MakeFSSM(BSTR startup)
{
UBYTE str[258];
STRPTR src = BADDR(startup);
struct RDArgs *rdargs;
if(src)
{
int i,len = src[0];
/* Convert startup string */
CopyMem(&src[1], str, len);
str[len] = '\n';
str[len+1] = '\0';
for(i=0;i<len;i++)
if(str[i] == '"') str[i] = ' ';
if((rdargs = (struct RDArgs*)AllocDosObject(DOS_RDARGS, NULL)))
{
static char template[]=
"D=DEVICE/A,"
"U=UNIT/N/A,"
"F=FLAGS/N,"
"NS=NOAUTOSCAN/S,"
"I=INTERLEAVE/N,"
"ICON/K";
rdargs->RDA_Flags |= RDAF_NOPROMPT;
rdargs->RDA_Source.CS_Buffer = str;
rdargs->RDA_Source.CS_Length = strlen(str);
rdargs->RDA_Source.CS_CurChr = 0;
if(ReadArgs(template, argarray, rdargs))
{
if((fssm = AllocVec(sizeof(struct FileSysStartupMsg), MEMF_PUBLIC)))
{
struct DosEnvec *env;
STRPTR name;
if((env = AllocVec(sizeof(struct DosEnvec), MEMF_PUBLIC|MEMF_CLEAR)))
{
if((name = AllocVec(strlen((STRPTR)argarray[0])+2, MEMF_PUBLIC)))
{
strcpy(name+1, (STRPTR)argarray[0]);
name[0] = strlen(name+1);
fssm->fssm_Unit = *(ULONG*)argarray[1];
fssm->fssm_Device = (BPTR)MKBADDR(name);
fssm->fssm_Flags = argarray[2] ? *(ULONG*)argarray[2] : 16;
fssm->fssm_Environ = (BPTR)MKBADDR(env);
/* These might be strange settings, but we must announce
the device as one single track with 683 sectors, other-
wise there would be some trouble with formatting etc. */
env->de_TableSize = 19;
env->de_SizeBlock = 256/4;
env->de_Surfaces = 1;
env->de_SectorPerBlock = 1;
env->de_BlocksPerTrack = 683;
env->de_LowCyl = 0;
env->de_HighCyl = 0;
env->de_DosType = ID_DOS_DISK;
env->de_MaxTransfer = 256*683;
env->de_Mask = 0x7ffffffe;
env->de_NumBuffers = 683;
env->de_Reserved = 1;
if(argarray[3])
autoscan = FALSE;
if(argarray[4])
{
LONG i = *(ULONG*)argarray[4];
if(i>0)
interleave = i;
}
return(TRUE);
}
FreeVec(env);
}
FreeVec(fssm);
}
FreeArgs(rdargs);
}
FreeDosObject(DOS_RDARGS, rdargs);
}
}
return(FALSE);
}
static void LoadDiskIcon() {
if(argarray[5]) {
BPTR fh;
if((fh = Open((STRPTR)argarray[5], MODE_OLDFILE))) {
ULONG len;
APTR data;
Seek(fh, 0, OFFSET_END);
len = Seek(fh, 0, OFFSET_BEGINNING);
if((data = AllocVec(len, MEMF_ANY))) {
if(Read(fh, data, len) != len) {
FreeVec(data);
data = NULL;
}
}
Close(fh);
if(data) {
diskiconimg = data;
diskiconlength = len;
}
}
}
}
void entry(void)
{
struct DosPacket *startuppacket;
struct DosList *devnode;
LONG error = ERROR_NO_FREE_STORE;
SysBase = *(volatile APTR*)4;
ourtask = FindTask(NULL);
ourport = &((struct Process *)ourtask)->pr_MsgPort;
WaitPort(ourport);
startuppacket = GetPacket(ourport);
devnode = (struct DosList*)BADDR(startuppacket->dp_Arg3);
if((ourport = CreateMsgPort())) {
if((DOSBase = (struct DosLibrary*)OpenLibrary(DOSNAME, 37)))
{
if((UtilityBase = (struct UtilityBase*)OpenLibrary("utility.library",37)))
{
__UtilityBase = UtilityBase;
/* I'm almost sure that using the MountList `Control' field
instead of `Startup' is better; well... next time ;-) */
if(MakeFSSM(startuppacket->dp_Arg2))
{
devnode->dol_misc.dol_handler.dol_Startup = (BPTR)MKBADDR(fssm);
if(!(error = InitDiskSS(&((STRPTR)BADDR(fssm->fssm_Device))[1],fssm->fssm_Unit,fssm->fssm_Flags)))
{
if(!(error = InitVolumeSS()))
{
ULONG pktsig = 1<<(ourport->mp_SigBit);
ULONG diskchgsig = 1<<diskchgintbit;
ULONG udssig = 1<<(UDStimer->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
ULONG mask = pktsig|diskchgsig|udssig;
error = 0;
devnode->dol_Task = ourport;
startuppacket->dp_Arg4 = (LONG)ourport;
ReturnPacket(startuppacket, DOSTRUE, 0);
LoadDiskIcon();
DoDiskInsert();
for(;;)
{
ULONG sigs;
while(!( SetSignal(0,0)&mask || LoadDisk() ));
sigs = Wait(mask);
if(sigs & pktsig)
DoPackets();
if(sigs & udssig)
UpdateDiskStructure();
if(sigs & diskchgsig)
{
if(!inhibited)
{
/* We do the remove for security reasons */
DoDiskRemove();
DoDiskInsert();
}
}
}
QuitVolumeSS();
}
QuitDiskSS();
}
} else error = ERROR_REQUIRED_ARG_MISSING;
CloseLibrary((struct Library*)UtilityBase);
}
CloseLibrary((struct Library*)DOSBase);
}
DeleteMsgPort(ourport);
}
ourport = &((struct Process *)ourtask)->pr_MsgPort;
if(error)
ReturnPacket(startuppacket, DOSFALSE, error);
}